package world;

import java.util.List;
import java.util.ArrayList;

import parsing.productions.Program;

public class Species {

	private CritterWorld world;
	// Attributes that define the species.
	private int speciesId;
	private int offense;
	private int defense;
	private int memLength;
	private Program genome;
	// Parent species. Null if root species.
	private Species parent;
	
	/**
	 * Creates a new Species object with the indicated speciesID.
	 * Parameters: species offense, defense, memLength, and Program. Unique to this species.
	 * @param parent The species this one came from. Null if root species.
	 */
	public Species(CritterWorld w, int offense, int defense, int memLength, int speciesId, Program genome, Species parent) {
		world = w;
		this.offense = offense;
		this.defense = defense;
		this.memLength = memLength;
		this.speciesId = speciesId;
		this.genome = genome;
		this.parent = parent;
	}
	
	/**
	 * Creates a new Species object with the indicated speciesID.
	 * Parameters: species offense, defense, memLength, and Program. Unique to this species.
	 * @param parent The species this one came from. Null if root species.
	 */
	public Species(CritterWorld w, int offense, int defense, int memLength, int speciesId, Program genome) {
		this(w, offense, defense, memLength, speciesId, genome, null);
	}
	
	@Override
	public boolean equals(Object compr) {
		if (!(compr instanceof Species)) return false;
		Species compSp = (Species) compr;
		if (offense != compSp.offense) return false;
		if (defense != compSp.defense) return false;
		if (memLength != compSp.memLength) return false;
		if ((genome == null && compSp.genome == null) || !genome.equals(compSp.genome)) return false;
		return true;
	}
	
	public boolean equals(int off, int def, int memLen, Program gen) {
		if (offense != off) return false;
		if (defense != def) return false;
		if (memLength != memLen) return false;
		if ((genome == null && gen == null) || !genome.equals(gen)) return false;
		return true;
	}

	public Program getProgram() {
		return genome;
	}

	public int getMemLength() {
		return memLength;
	}

	public int getDefense() {
		return defense;
	}

	public int getOffense() {
		return offense;
	}
	
	public Species getParent() {
		return parent;
	}
	
	public int getSpeciesId() {
		return speciesId;
	}
	
	public List<Integer> lineage(){
		ArrayList<Integer> lineage = new ArrayList<Integer>();
		Species s = this;
		lineage.add(speciesId);
		while(s.parent != null){
			s = s.parent;
			lineage.add(s.speciesId);
		}
		return lineage;
	}
	
}